/**
  **************************************************************************
  * @file     at32f421_clock.c
  * @brief    system clock config program
  **************************************************************************
  *                       Copyright notice & Disclaimer
  *
  * The software Board Support Package (BSP) that is made available to
  * download from Artery official website is the copyrighted work of Artery.
  * Artery authorizes customers to use, copy, and distribute the BSP
  * software and its related documentation for the purpose of design and
  * development in conjunction with Artery microcontrollers. Use of the
  * software is governed by this copyright notice and the following disclaimer.
  *
  * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  *
  **************************************************************************
  */

/* includes ------------------------------------------------------------------*/
#include "at32f421_clock.h"

/** @addtogroup AT32F421_periph_template
  * @{
  */

/** @addtogroup 421_System_clock_configuration System_clock_configuration
  * @{
  */

/**
  * @brief  system clock config program
  * @note   the system clock is configured as follow:
  *         - system clock        = hext * pll_mult
  *         - system clock source = pll (hext)
  *         - hext                = 8000000
  *         - sclk                = 120000000
  *         - ahbdiv              = 1
  *         - ahbclk              = 120000000
  *         - apb2div             = 1
  *         - apb2clk             = 120000000
  *         - apb1div             = 1
  *         - apb1clk             = 120000000
  *         - pll_mult            = 15
  *         - flash_wtcyc         = 3 cycle
  * @param  none
  * @retval none
  */
/**
 * 配置系统时钟。
 * 
 * 此函数初始化系统时钟源，选择PLL作为系统时钟源，并配置AHB和APB总线时钟。
 * 它确保系统时钟以期望的频率运行，并优化时钟分配以提高能效。
 * 
 * 注意：此函数依赖于特定的CRM（时钟资源管理）API实现，这些实现在这里没有显示。
 */

void system_clock_config(void)
{
  // 设置闪存访问等待周期，根据系统时钟频率确保正确的闪存访问。
  // 配置闪存预取寄存器
  flash_psr_set(FLASH_WAIT_CYCLE_3);

  // 重置CRM到其默认状态，在配置时钟源之前。
  // 重置CRM
  crm_reset();

  // 启用外部高速振荡器（HXT）作为CRM时钟源。
  // 启用HXT
  crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);

  // 等待直到HXT振荡器稳定，然后才能继续配置PLL。
  // 等待HXT准备就绪
  while(crm_hext_stable_wait() == ERROR)
  {
  }

  // 配置PLL使用HXT作为输入源，并将频率乘以15。
  // 配置PLL时钟资源
  crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_15);

  // 启用PLL作为时钟源。
  // 等待PLL准备就绪
  while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
  {
  }

  // 配置AHB总线时钟分频因子为1，设置AHB时钟频率与PLL输出相同。
  // 配置AHBCLK
  crm_ahb_div_set(CRM_AHB_DIV_1);

  // 配置APB2总线时钟，APB1/APB2的最大频率为120MHz。
  // 配置APB2CLK
  crm_apb2_div_set(CRM_APB2_DIV_1);

  // 配置APB1总线时钟，APB1/APB2的最大频率为120MHz。
  // 配置APB1CLK
  crm_apb1_div_set(CRM_APB1_DIV_1);

  // 启用自动步进模式，该模式下PLL会根据负载自动调整频率。
  // 启用自动步进模式
  crm_auto_step_mode_enable(TRUE);

  // 选择PLL作为系统时钟源。
  // 切换系统时钟源至PLL
  crm_sysclk_switch(CRM_SCLK_PLL);

  // 等待直到PLL被用作系统时钟源。
  // 等待PLL被用作系统时钟源
  while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
  {
  }

  // 禁用自动步进模式。
  // 禁用自动步进模式
  crm_auto_step_mode_enable(FALSE);

  // 更新system_core_clock全局变量，反映当前系统核心时钟频率。
  // 更新系统核心时钟
  system_core_clock_update();
}

/**
  * @}
  */

/**
  * @}
  */

